package com.itheima.app.mapper;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class VideoManager {

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private CommentService commentService;

    @Reference
    private VideoService videoService;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private FocusUserService focusUserService;


    @Autowired
    private MQVideoManager mqVideoManager;

    //查询推荐给我的视频
//    @Cacheable(value = "tanhua", key = "'video_'+#userId+'_'+#pageNum+'_'+#pageSize")
    public PageBeanVo findRecommendVideo(Long userId, Integer pageNum, Integer pageSize) {

        //2. 调用service分页查询推荐给我的视频详情
        PageBeanVo pageBeanVo = videoService.findRecommendVideo(userId, pageNum, pageSize);

        //3. 封装返回结果
        List<Video> videoList = (List<Video>) pageBeanVo.getItems();
        List<VideoVo> videoVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(videoList)) {
            for (Video video : videoList) {
                VideoVo videoVo = new VideoVo();

                //3-1 设置视频发布人信息
                UserInfo userInfo = userInfoService.findById(video.getUserId());
                BeanUtils.copyProperties(userInfo, videoVo);

                //3-2 设置视频信息
                BeanUtils.copyProperties(video, videoVo);

                //3-3 设置上面没有赋值成功的
                videoVo.setId(video.getId().toHexString());//设置视频id
                videoVo.setCover(video.getPicUrl());//视频封面
                videoVo.setSignature(video.getText());//视频签名

                //todo 临时模拟
                videoVo.setHasLiked(1);//是否喜欢

                //查看是否关注，redis中是否存在key  //
                String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.getUser().getId(), video.getUserId());
                if (stringRedisTemplate.hasKey(key)) {
                    videoVo.setHasFocus(1);//关注
                } else {
                    videoVo.setHasFocus(0);//未关注
                }

                //查看是否点赞视频
                boolean s = stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getUser().getId(), video.getId()));
                if(s){
                    videoVo.setHasLiked(1);//点赞
                }else {
                    videoVo.setHasLiked(0);//没点赞
                }

                videoVoList.add(videoVo);
            }

        }
        pageBeanVo.setItems(videoVoList);
        return pageBeanVo;
    }

    //发布视频
//    @CacheEvict( key="'vadio_'+#userId+':*'",value = "tanhua")//清空缓存
    public void saveVideo(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //1. 将图片上传到阿里云
        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());

        //2. 将视频上传到fastDFS
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(),
                FileUtil.extName(videoFile.getOriginalFilename()), null);
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();

        //3. 组装video
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(userId);
        video.setText("看得见风科技规划法规。。。");
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);

        //4. 执行保存
        videoService.save(video);

        //向mq投递消息(大数据推荐)
        mqVideoManager.sendVideoMsg(video.getId().toHexString(), MQVideoManager.VIDEO_PUBLISH);
    }

    //关注用户
    public void userFocus(Long focusId) {
        //1. 组装focus对象
        FocusUser focusUser = new FocusUser();
        focusUser.setCreated(System.currentTimeMillis());
        focusUser.setUserId(UserHolder.getUser().getId());//登录用户id
        focusUser.setFocusUserId(focusId);//视频发布用户id

        //2. 调用service保存关注
        focusUserService.save(focusUser);

        //3. 在redis中生成关注标识    focus_user:{}_{}
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.getUser().getId(), focusId);
        stringRedisTemplate.opsForValue().set(key, "1");
    }

    //取消关注用户
    public void userUnFocus(Long focusId) {
        //1. 组装focus对象
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(UserHolder.getUser().getId());//登录用户id
        focusUser.setFocusUserId(focusId);//视频发布用户id

        //2. 调用service删除关注
        focusUserService.delete(focusUser);

        //3. 从redis中删除关注标识   focus_user:{}_{}
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.getUser().getId(), focusId);
        stringRedisTemplate.delete(key);
    }


    //视频点赞
    public Integer videoLike(String videoId) {
        // 1组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//视频id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.getUser().getId());

        //2.调用service完成喜欢
        Integer count = commentService.saveVideoComment(comment);

        //3. 向redis中记录喜欢操作
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getUser().getId(), videoId), "1");

        //向mq投递消息(大数据推荐)
        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_LIKE);
        return count;
    }

    //取消视频点赞
    public Integer videoDisLike(String videoId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//动态id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.getUser().getId());//操作人id
        //2. 调用service完成取消点赞
        Integer count = commentService.deleteVideoComment(comment);
        //3. 向redis中删除点赞操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getUser().getId(), videoId));

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_DISLIKE);
        return count;
    }

    //对视频评论
    public Integer saveComment(String videoId, String commentContent) {
        //1.组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//动态id
        comment.setCommentType(2);//评论
        comment.setUserId(UserHolder.getUser().getId());//评论人
        comment.setContent(commentContent);//评论内容
        //2.调用service保存评论
        Integer count = commentService.saveVideoComment(comment);

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_COMMENT);
        return count;
    }

    //查询视频评论列表
    public PageBeanVo findVideoComment(String videoId, Integer pageNum, Integer pageSize) {
        //1.调用service查询列表
        PageBeanVo pageBeanVo = commentService.findCommentByVideo(videoId,pageNum,pageSize);
        //组装返回结果
        List<Comment> commentList = ( List<Comment>) pageBeanVo.getItems();
        //创建临时集合
        List<CommentVo> commentVoList = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                //3.创建commentVo 来封装前端返回的对象中的集合部分
                CommentVo commentVo = new CommentVo();
                //3-1 设置评论信息
                commentVo.setId(comment.getId().toHexString());//评论id
                commentVo.setContent(comment.getContent());//评论内容
                commentVo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated())));//评论发布时间
                //3-2 设置评论发布人的信息
                Long userId = comment.getUserId();//获取评论者Id
                UserInfo userInfo = userInfoService.findById(userId);//评论人信息
                commentVo.setAvatar(userInfo.getAvatar());//评论者头像
                commentVo.setNickname(userInfo.getNickname());//评论者昵称

                //查看是否点赞视频评论
                boolean s = stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getUser().getId(), comment.getId()));
                if(s){
                    commentVo.setHasLiked(1);//点赞
                }else {
                    commentVo.setHasLiked(0);//没点赞
                }

                //3-3 存储到临时集合
                commentVoList.add(commentVo);
            }
        }
        //4 替换分页对象中的items(List<Comment>---->List<CommentVo>)
        pageBeanVo.setItems(commentVoList);

        //5.返回结果
        return pageBeanVo;
    }

    //视频评论点赞
    public Integer videoCommentLike(String commentId) {
        // 1组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(commentId));//视频id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.getUser().getId());

        //2.调用service完成喜欢
        Integer count = commentService.saveVideoCommentLike(comment);

        //3. 向redis中记录喜欢操作
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getUser().getId(), commentId), "1");
        return count;
    }
    //取消视频评论点赞
    public Integer videoCommentDisLike(String commentId) {
        // 1组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(commentId));//视频id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.getUser().getId());

        //2.调用service完成喜欢
        Integer count = commentService.deleteVideoCommentLike(comment);

        //3. 向redis中记录喜欢操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getUser().getId(), commentId));
        return count;
    }
}

